package com.doctracker.service;

import com.doctracker.model.Person;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据管理服务类
 * 负责保存和加载人员名单到本地文件
 */
public class DataManager {
    
    /**
     * 数据存储目录
     */
    private static final String DATA_DIR = System.getProperty("user.home") + File.separator + ".doctracker";
    
    /**
     * 名单文件存储目录
     */
    private static final String LISTS_DIR = DATA_DIR + File.separator + "lists";
    
    /**
     * 历史记录文件
     */
    private static final String HISTORY_FILE = DATA_DIR + File.separator + "history.json";
    
    /**
     * JSON处理器
     */
    private final ObjectMapper objectMapper;
    
    /**
     * 构造函数
     */
    public DataManager() {
        this.objectMapper = new ObjectMapper();
        this.objectMapper.registerModule(new JavaTimeModule());
        
        // 确保目录存在
        createDirectories();
    }
    
    /**
     * 创建必要的目录
     */
    private void createDirectories() {
        try {
            File dataDir = new File(DATA_DIR);
            if (!dataDir.exists()) {
                dataDir.mkdirs();
                System.out.println("创建数据目录: " + DATA_DIR);
            }
            
            File listsDir = new File(LISTS_DIR);
            if (!listsDir.exists()) {
                listsDir.mkdirs();
                System.out.println("创建名单目录: " + LISTS_DIR);
            }
        } catch (Exception e) {
            System.err.println("创建目录失败: " + e.getMessage());
        }
    }
    
    /**
     * 保存人员名单
     * 
     * @param people 人员列表
     * @param listName 名单名称
     * @return 是否保存成功
     */
    public boolean savePeopleList(List<Person> people, String listName) {
        try {
            // 生成文件名（包含时间戳）
            String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
            String fileName = sanitizeFileName(listName) + "_" + timestamp + ".json";
            String filePath = LISTS_DIR + File.separator + fileName;
            
            // 创建简化的人员数据（只保存姓名）
            List<String> nameList = people.stream()
                .map(Person::getName)
                .collect(java.util.stream.Collectors.toList());
            
            // 创建保存的数据结构
            Map<String, Object> data = new HashMap<>();
            data.put("name", listName);
            data.put("saveTime", LocalDateTime.now());
            data.put("totalCount", people.size());
            data.put("people", nameList); // 只保存姓名列表
            
            // 保存到文件
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(new File(filePath), data);
            
            // 更新历史记录
            addToHistory(listName, fileName, people.size());
            
            System.out.println("名单保存成功: " + filePath);
            return true;
            
        } catch (IOException e) {
            System.err.println("保存名单失败: " + e.getMessage());
            e.printStackTrace();
            return false;
        }
    }
    
    /**
     * 加载人员名单
     * 
     * @param fileName 文件名
     * @return 人员列表
     */
    public List<Person> loadPeopleList(String fileName) {
        try {
            String filePath = LISTS_DIR + File.separator + fileName;
            File file = new File(filePath);
            
            if (!file.exists()) {
                System.err.println("名单文件不存在: " + filePath);
                return new ArrayList<>();
            }
            
            // 读取文件内容
            Map<String, Object> data = objectMapper.readValue(file, new TypeReference<Map<String, Object>>() {});
            
            List<Person> people = new ArrayList<>();
            Object peopleData = data.get("people");
            
            if (peopleData instanceof List) {
                List<?> list = (List<?>) peopleData;
                
                for (Object item : list) {
                    if (item instanceof String) {
                        // 新格式：直接是姓名字符串
                        people.add(new Person((String) item));
                    } else if (item instanceof Map) {
                        // 旧格式：Person对象
                        Map<?, ?> personMap = (Map<?, ?>) item;
                        String name = (String) personMap.get("name");
                        if (name != null) {
                            people.add(new Person(name));
                        }
                    }
                }
            }
            
            System.out.println("名单加载成功: " + fileName + ", 共" + people.size() + "人");
            return people;
            
        } catch (IOException e) {
            System.err.println("加载名单失败: " + e.getMessage());
            e.printStackTrace();
            return new ArrayList<>();
        }
    }
    
    /**
     * 获取历史名单列表
     * 
     * @return 历史名单列表
     */
    public List<HistoryItem> getHistoryList() {
        try {
            File historyFile = new File(HISTORY_FILE);
            if (!historyFile.exists()) {
                // 如果历史记录文件不存在，尝试重建
                return rebuildHistoryFromFiles();
            }
            
            List<HistoryItem> history = objectMapper.readValue(historyFile, new TypeReference<List<HistoryItem>>() {});
            
            // 过滤掉不存在的文件
            List<HistoryItem> validHistory = history.stream()
                .filter(item -> new File(LISTS_DIR + File.separator + item.getFileName()).exists())
                .collect(java.util.stream.Collectors.toList());
            
            // 检查是否有文件没有在历史记录中
            List<HistoryItem> allItems = rebuildHistoryFromFiles();
            for (HistoryItem newItem : allItems) {
                boolean exists = validHistory.stream()
                    .anyMatch(item -> item.getFileName().equals(newItem.getFileName()));
                if (!exists) {
                    validHistory.add(newItem);
                }
            }
            
            // 按时间排序（最新的在前面）
            validHistory.sort((a, b) -> b.getSaveTime().compareTo(a.getSaveTime()));
            
            return validHistory;
                
        } catch (IOException e) {
            System.err.println("读取历史记录失败，重新扫描文件夹: " + e.getMessage());
            
            // 如果读取失败，删除损坏的历史记录文件，重新扫描
            File historyFile = new File(HISTORY_FILE);
            if (historyFile.exists()) {
                historyFile.delete();
                System.out.println("已删除损坏的历史记录文件");
            }
            
            return rebuildHistoryFromFiles();
        }
    }
    
    /**
     * 从文件夹中重建历史记录
     * 扫描lists文件夹中的所有JSON文件，重新创建历史记录
     * 
     * @return 历史记录列表
     */
    private List<HistoryItem> rebuildHistoryFromFiles() {
        List<HistoryItem> historyItems = new ArrayList<>();
        
        try {
            File listsDir = new File(LISTS_DIR);
            if (!listsDir.exists()) {
                return historyItems;
            }
            
            File[] files = listsDir.listFiles((dir, name) -> name.endsWith(".json"));
            if (files == null) {
                return historyItems;
            }
            
            System.out.println("正在重建历史记录，发现 " + files.length + " 个名单文件");
            
            for (File file : files) {
                try {
                    // 读取文件获取名单信息
                    Map<String, Object> data = objectMapper.readValue(file, new TypeReference<Map<String, Object>>() {});
                    
                    HistoryItem item = new HistoryItem();
                    item.setFileName(file.getName());
                    item.setName((String) data.get("name"));
                    item.setPeopleCount((Integer) data.get("totalCount"));
                    
                    // 解析保存时间
                    Object saveTimeObj = data.get("saveTime");
                    if (saveTimeObj instanceof String) {
                        item.setSaveTime(LocalDateTime.parse((String) saveTimeObj));
                    } else if (saveTimeObj instanceof List) {
                        // 处理旧格式的时间数组
                        List<?> timeArray = (List<?>) saveTimeObj;
                        if (timeArray.size() >= 6) {
                            int year = (Integer) timeArray.get(0);
                            int month = (Integer) timeArray.get(1);
                            int day = (Integer) timeArray.get(2);
                            int hour = (Integer) timeArray.get(3);
                            int minute = (Integer) timeArray.get(4);
                            int second = (Integer) timeArray.get(5);
                            item.setSaveTime(LocalDateTime.of(year, month, day, hour, minute, second));
                        }
                    } else {
                        // 如果无法解析时间，使用文件修改时间
                        item.setSaveTime(LocalDateTime.ofEpochSecond(
                            file.lastModified() / 1000, 0, 
                            java.time.ZoneOffset.systemDefault().getRules().getOffset(java.time.Instant.now())
                        ));
                    }
                    
                    historyItems.add(item);
                    System.out.println("重建历史记录: " + item.getName() + " (" + item.getPeopleCount() + "人)");
                    
                } catch (Exception e) {
                    System.err.println("解析文件失败: " + file.getName() + " - " + e.getMessage());
                }
            }
            
            // 保存重建的历史记录
            if (!historyItems.isEmpty()) {
                objectMapper.writerWithDefaultPrettyPrinter().writeValue(new File(HISTORY_FILE), historyItems);
                System.out.println("历史记录重建完成，共 " + historyItems.size() + " 个名单");
            }
            
        } catch (Exception e) {
            System.err.println("重建历史记录失败: " + e.getMessage());
        }
        
        return historyItems;
    }
    
    /**
     * 添加到历史记录
     * 
     * @param listName 名单名称
     * @param fileName 文件名
     * @param peopleCount 人员数量
     */
    private void addToHistory(String listName, String fileName, int peopleCount) {
        try {
            List<HistoryItem> history = getHistoryList();
            
            // 创建新的历史项
            HistoryItem newItem = new HistoryItem();
            newItem.setName(listName);
            newItem.setFileName(fileName);
            newItem.setSaveTime(LocalDateTime.now());
            newItem.setPeopleCount(peopleCount);
            
            // 添加到历史记录开头
            history.add(0, newItem);
            
            // 限制历史记录数量（保留最近20个）
            if (history.size() > 20) {
                history = history.subList(0, 20);
            }
            
            // 保存历史记录
            objectMapper.writerWithDefaultPrettyPrinter().writeValue(new File(HISTORY_FILE), history);
            
        } catch (IOException e) {
            System.err.println("更新历史记录失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除名单文件
     * 
     * @param fileName 文件名
     * @return 是否删除成功
     */
    public boolean deleteList(String fileName) {
        try {
            File file = new File(LISTS_DIR + File.separator + fileName);
            if (file.exists() && file.delete()) {
                System.out.println("删除名单文件: " + fileName);
                return true;
            }
            return false;
        } catch (Exception e) {
            System.err.println("删除文件失败: " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 清理文件名中的非法字符
     * 
     * @param fileName 原文件名
     * @return 清理后的文件名
     */
    private String sanitizeFileName(String fileName) {
        // 移除或替换文件名中的非法字符
        return fileName.replaceAll("[\\\\/:*?\"<>|]", "_").trim();
    }
    
    /**
     * 历史记录项
     */
    @JsonIgnoreProperties(ignoreUnknown = true) // 忽略未知字段
    public static class HistoryItem {
        private String name;
        private String fileName;
        private LocalDateTime saveTime;
        private int peopleCount;
        
        // Getter和Setter方法
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
        
        public String getFileName() { return fileName; }
        public void setFileName(String fileName) { this.fileName = fileName; }
        
        public LocalDateTime getSaveTime() { return saveTime; }
        public void setSaveTime(LocalDateTime saveTime) { this.saveTime = saveTime; }
        
        public int getPeopleCount() { return peopleCount; }
        public void setPeopleCount(int peopleCount) { this.peopleCount = peopleCount; }
        
        /**
         * 获取显示文本
         * @return 显示文本
         */
        public String getDisplayText() {
            String timeStr = saveTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            return String.format("%s (%d人) - %s", name, peopleCount, timeStr);
        }
        
        @Override
        public String toString() {
            return getDisplayText();
        }
    }
} 